package com.free.semantic.core.impl.demo;

import com.free.semantic.common.Ls;
import com.free.semantic.common.ParamNode;
import com.free.semantic.common.RelationChain;
import com.free.semantic.core.ConceptInstanceManage;
import com.free.semantic.core.ConceptManage;
import com.free.semantic.core.impl.BaseTest;
import com.free.semantic.core.impl.ConceptInstanceManageImpl;
import com.free.semantic.core.script.SemanticNetEngine;
import com.free.semantic.core.script.impl.ScriptEngineImpl;
import com.free.semantic.req.RelationDefineGroup;
import com.free.semantic.utils.Utils;
import org.junit.jupiter.api.Test;

import java.util.List;

import static com.free.semantic.common.RangeObj.one;

/**
 * 跨模型时候隐含条件融合
 */
public class Demo4_impliedCondition extends BaseTest {

    @Test
    public void test() {

        /**
         * 原始认知对应的模型
         */
        RelationDefineGroup groupOne = new RelationDefineGroup();
        // 找到
        defineRelation(groupOne, "找到", defineItem(oneObj("A"), oneObj("B")));

        //定义一个语义网络
        ConceptManage modelOne = getConceptManage(groupOne);
        //object 中国手机号 人
        modelOne.addConcept("中国手机号", "人");
        //找到(中国手机号,人)
        createRelation(modelOne, "找到", "中国手机号", "人");

        {
            List<RelationChain> relationChains = modelOne.findAllRelationChain(Ls.of("中国手机号"), "人");
            System.out.println(relationChains.get(0));// 输出： 来源事物为：中国手机号，目标事物为人，执行路径为 [中国手机号->人]
        }

        /**
         * 认知更新后的模型变化
         */
        RelationDefineGroup groupTwo = new RelationDefineGroup();
        // 二元映射 找到
        defineRelation(groupTwo, "二元映射", defineItem(oneObj("A", "B"), oneObj("C")));
        defineRelation(groupTwo, "找到", defineItem(oneObj("A"), oneObj("B")));

        //定义一个语义网络
        ConceptManage modelTwo = getConceptManage(groupTwo);
        //object 人 体重
        modelTwo.addConcept("中国手机号", "人", "手机号", "国家区号");
        //二元映射(手机号,国家区号,人)
        createRelation2(modelTwo, "二元映射", "手机号", "国家区号", "人");

        createRelation(modelTwo, "找到", "中国手机号", "手机号");
        createRelation(modelTwo, "找到", "中国手机号", "国家区号");

        {
            List<RelationChain> relationChains = modelTwo.findAllRelationChain(Ls.of("手机号"), "人");
            System.out.println(relationChains.get(0));// 输出： 来源事物为：手机号,国家区号，目标事物为人，执行路径为 [手机号,国家区号->人]
        }

        {
            List<RelationChain> relationChains = modelTwo.findAllRelationChain(Ls.of("中国手机号"), "人");
            System.out.println(relationChains.get(0));// 输出： 来源事物为：中国手机号，目标事物为人，执行路径为 [中国手机号->手机号]，[中国手机号->国家区号]，[手机号,国家区号->人]
            assertObj(relationChains.get(0).getSourceObjectList(), "中国手机号");
        }
    }

    @Test
    public void test3() {

        /**
         * 原始认知对应的模型
         */
        RelationDefineGroup groupOne = new RelationDefineGroup();
        // 找到
        defineRelation(groupOne, "找到", defineItem(oneObj("A"), oneObj("B")));

        //定义一个语义网络
        ConceptManage modelOne = getConceptManage(groupOne);
        //object 中国手机号 人
        modelOne.addConcept("中国手机号", "人");
        //找到(中国手机号,人)
        createRelation(modelOne, "找到", "中国手机号", "人");

        {
            List<RelationChain> relationChains = modelOne.findAllRelationChain(Ls.of("中国手机号"), "人");
            System.out.println(relationChains.get(0));// 输出： 来源事物为：中国手机号，目标事物为人，执行路径为 [中国手机号->人]
        }


        /**
         * 认知更新后的模型变化
         */
        RelationDefineGroup groupTwo = new RelationDefineGroup();
        // 二元映射 找到
        defineRelation(groupTwo, "二元映射", defineItem(oneObj("A", "B"), oneObj("C")));
        defineRelation(groupTwo, "找到", defineItem(oneObj("A"), oneObj("B")));

        //定义一个语义网络
        ConceptManage modelTwo = getConceptManage(groupTwo);
        //object 人 体重
        modelTwo.addConcept("联系人", "手机号", "国家区号");
        //二元映射(手机号,国家区号,人)
        createRelation2(modelTwo, "二元映射", "手机号", "国家区号", "联系人");

        ConceptInstanceManage modelTwoInstance = new ConceptInstanceManageImpl(modelTwo, Utils.buildMap(
                new String[]{"手机号", "国家区号"}, "联系人",
                new String[][]{{"13412341234", "86", "张三"}}));


        String mergeScript = "object 中国手机号 人\n"
                + "relation 找到2(A,B)\n"
                + "A->B=1\n"
                + "找到2(中国手机号,手机号)\n"
                + "找到2(中国手机号,国家区号)\n"
                + "找到2(联系人,人)\n"
                + "buildMap((中国手机号,国家区号),(13412341234,86))\n"
                + "buildMap((中国手机号,手机号),(13412341234,13412341234))\n"
                + "buildMap((联系人,人),(张三,张三))\n"
                + "eq 中国手机号=中国手机号\n"
                + "eq 人=人\n";

        SemanticNetEngine engine = new ScriptEngineImpl();
        ConceptInstanceManage instanceManage = engine.execScript(modelOne, mergeScript, modelTwoInstance);

        List<RelationChain> relationChains = instanceManage.concept().findAllRelationChain(Ls.of("中国手机号"), "人");
        System.out.println(relationChains);

        List<Object> objects = instanceManage.goByLocatorNode(Ls.of(new ParamNode("中国手机号", "13412341234")), one("人"));

        System.out.println(objects);
        assert objects.get(0).equals("张三");

    }


}
